import datetime
import os
import subprocess
import time

import uiautomator2 as u2
from PIL import Image, ImageDraw, ImageFont


def check_adb_environment():
    """检查ADB环境是否正常"""
    try:
        # 检查ADB是否安装
        version = subprocess.check_output(["adb", "version"], stderr=subprocess.STDOUT).decode("utf-8")
        print(f"ADB版本: {version.strip()}")

        # 检查设备连接
        devices = subprocess.check_output(["adb", "devices"], stderr=subprocess.STDOUT).decode("utf-8")

        # 解析设备列表
        device_list = []
        for line in devices.strip().split("\n")[1:]:
            if line.strip():
                device_id, status = line.strip().split("\t", 1)
                device_list.append((device_id, status))

        if not device_list:
            print("错误：未检测到连接的安卓设备。请确保设备已通过USB连接并开启USB调试模式。")
            return False
        elif any(status != "device" for _, status in device_list):
            print("错误：设备未授权或连接异常。请在设备上确认授权提示。")
            return False
        else:
            print(f"已连接设备: {len(device_list)}台")
            for device_id, status in device_list:
                print(f"  - {device_id} ({status})")
            return True

    except FileNotFoundError:
        print("错误：未找到ADB命令。请确保ADB已安装并添加到系统环境变量。")
        return False
    except subprocess.CalledProcessError as e:
        print(f"ADB命令执行失败: {e.output.decode('utf-8')}")
        return False


def connect_device():
    """连接安卓设备并返回设备对象"""
    try:
        print("正在连接设备...")
        device = u2.connect()
        print(f"设备连接成功: {device.serial}")
        print(f"设备信息: {device.info}")
        return device
    except Exception as e:
        print(f"设备连接失败: {str(e)}")
        return None


def take_screenshot_with_coordinates(device, screenshot_name="screenshot.png", show_grid=True, grid_step=100):
    """截取当前屏幕并添加坐标信息和网格
    
    Args:
        device: uiautomator2设备对象
        screenshot_name: 截图文件名
        show_grid: 是否显示网格
        grid_step: 网格间距
        
    Returns:
        tuple: (str, tuple) 截图保存路径和屏幕分辨率
    """
    try:
        # 获取当前文件所在目录
        game_folder = os.path.dirname(os.path.abspath(__file__))
        temp_screenshot_path = os.path.join(game_folder, f"temp_{screenshot_name}")
        final_screenshot_path = os.path.join(game_folder, screenshot_name)

        # 截取屏幕
        device.screenshot(temp_screenshot_path)

        # 获取屏幕分辨率
        width, height = device.window_size()

        # 打开截图并添加坐标信息
        try:
            image = Image.open(temp_screenshot_path)
            draw = ImageDraw.Draw(image)

            # 使用中文字体（如果系统有可用的中文字体）
            try:
                font = ImageFont.truetype("simhei.ttf", 20)  # 尝试使用黑体
            except:
                try:
                    font = ImageFont.truetype("Arial.ttf", 20)  # 尝试使用Arial
                except:
                    font = None  # 使用默认字体

            # 添加屏幕分辨率信息
            resolution_text = f"分辨率: {width}x{height}"
            draw.text((10, 10), resolution_text, fill=(255, 0, 0), font=font)

            # 添加网格和坐标刻度
            if show_grid:
                # 绘制垂直线和X坐标
                for x in range(0, width, grid_step):
                    draw.line([(x, 0), (x, height)], fill=(0, 255, 0, 128), width=1)
                    draw.text((x + 5, 40), f"X:{x}", fill=(0, 255, 0), font=font)

                # 绘制水平线和Y坐标
                for y in range(0, height, grid_step):
                    draw.line([(0, y), (width, y)], fill=(0, 255, 0, 128), width=1)
                    draw.text((width - 60, y + 5), f"Y:{y}", fill=(0, 255, 0), font=font)

            # 添加四个角落的坐标
            corners = [
                (0, 0, "左上角 (0,0)"),
                (width - 1, 0, f"右上角 ({width - 1},0)"),
                (0, height - 1, f"左下角 (0,{height - 1})"),
                (width - 1, height - 1, f"右下角 ({width - 1},{height - 1})")
            ]

            for x, y, text in corners:
                if x < width // 2 and y < height // 2:
                    # 左上角，文字在右下角
                    draw.text((x + 5, y + 5), text, fill=(255, 0, 0), font=font)
                elif x >= width // 2 and y < height // 2:
                    # 右上角，文字在左下角
                    text_width = len(text) * 10  # 粗略估计文本宽度
                    draw.text((x - text_width - 5, y + 5), text, fill=(255, 0, 0), font=font)
                elif x < width // 2 and y >= height // 2:
                    # 左下角，文字在右上角
                    draw.text((x + 5, y - 30), text, fill=(255, 0, 0), font=font)
                else:
                    # 右下角，文字在左上角
                    text_width = len(text) * 10  # 粗略估计文本宽度
                    draw.text((x - text_width - 5, y - 30), text, fill=(255, 0, 0), font=font)

            # 保存带有坐标信息的截图
            image.save(final_screenshot_path)
            print(f"已截取屏幕并添加坐标信息，保存到: {final_screenshot_path}")

            # 删除临时文件
            if os.path.exists(temp_screenshot_path):
                os.remove(temp_screenshot_path)

        except Exception as img_err:
            print(f"添加坐标信息时出错: {str(img_err)}")
            # 如果添加坐标信息失败，使用原始截图
            if os.path.exists(temp_screenshot_path):
                if os.path.exists(final_screenshot_path):
                    os.remove(final_screenshot_path)
                os.rename(temp_screenshot_path, final_screenshot_path)
                print(f"已使用原始截图，保存到: {final_screenshot_path}")

        return (final_screenshot_path, (width, height))
    except Exception as e:
        print(f"截图失败: {str(e)}")
        # 清理临时文件
        if os.path.exists(temp_screenshot_path):
            os.remove(temp_screenshot_path)
        return (None, None)


def safe_click(device, x, y, delay=1, max_retries=3):
    """安全点击操作，支持重试机制
    
    Args:
        device: uiautomator2设备对象
        x: 点击的X坐标
        y: 点击的Y坐标
        delay: 每次点击后的等待时间（秒）
        max_retries: 最大重试次数
        
    Returns:
        bool: 点击是否成功
    """
    for retry in range(max_retries):
        try:
            print(f"正在点击坐标 ({x}, {y})，尝试次数: {retry + 1}/{max_retries}")
            device.click(x, y)
            time.sleep(delay)
            return True
        except Exception as e:
            print(f"点击失败: {str(e)}")
            if retry < max_retries - 1:
                print("将尝试重新连接设备并再次点击...")
                try:
                    # 尝试重新连接设备
                    device = u2.connect()
                except:
                    print("设备重连失败")
                time.sleep(2)  # 等待2秒后重试
            else:
                print("已达到最大重试次数，点击操作失败")
    return False


def drag_screen(device, start_x, start_y, end_x, end_y, duration=0.5, max_retries=3):
    """屏幕拖动操作，支持重试机制
    
    Args:
        device: uiautomator2设备对象
        start_x: 拖动开始的X坐标
        start_y: 拖动开始的Y坐标
        end_x: 拖动结束的X坐标
        end_y: 拖动结束的Y坐标
        duration: 拖动持续时间（秒）
        max_retries: 最大重试次数
        
    Returns:
        bool: 拖动是否成功
    """
    for retry in range(max_retries):
        try:
            print(f"正在从 ({start_x}, {start_y}) 拖动到 ({end_x}, {end_y})，尝试次数: {retry + 1}/{max_retries}")
            device.drag(start_x, start_y, end_x, end_y, duration)
            return True
        except Exception as e:
            print(f"拖动失败: {str(e)}")
            if retry < max_retries - 1:
                print("将尝试重新连接设备并再次拖动...")
                try:
                    # 尝试重新连接设备
                    device = u2.connect()
                except:
                    print("设备重连失败")
                time.sleep(2)  # 等待2秒后重试
            else:
                print("已达到最大重试次数，拖动操作失败")
    return False


def calculate_time_difference(start_time, end_time):
    """计算两个时间的差值，并以时分秒格式返回"""
    if start_time > end_time:
        # 确保开始时间早于结束时间
        start_time, end_time = end_time, start_time

    time_diff = end_time - start_time
    total_seconds = int(time_diff.total_seconds())

    # 转换为时分秒
    hours = total_seconds // 3600
    minutes = (total_seconds % 3600) // 60
    seconds = total_seconds % 60

    return hours, minutes, seconds


def main():
    """主函数：连接安卓设备并获取带坐标信息的截图"""
    print("=== 安卓设备连接与坐标截图工具 ===")
    print("本工具可以：")
    print("1. 检查ADB环境并连接安卓设备")
    print("2. 获取设备屏幕分辨率")
    print("3. 截取带有坐标网格和刻度的屏幕截图")
    print("4. 计算常用坐标点，方便进行点击操作")
    print("5. 提供点击操作的示例代码")
    print("6. 提供两个公用方法：safe_click（安全点击）和drag_screen（屏幕拖动）")

    # 检查ADB环境
    if not check_adb_environment():
        print("ADB环境异常，程序退出")
        return
    # 连接设备
    device = connect_device()
    if not device:
        print("无法连接设备，程序退出")
        return
    # 获取屏幕分辨率
    start_time = datetime.datetime.now()
    # 自动游戏循环计数器
    round_count = 0
    # 获取当前文件的完整路径
    current_path = os.path.realpath(__file__)
    # 获取带后缀的文件名（如 "test.py"）
    file_name = os.path.basename(current_path)
    # 分割文件名和后缀，取主文件名（去掉后缀）
    file_name_without_ext = os.path.splitext(file_name)[0]
    while True:
        round_count += 1
        print(f"\n\n=== {file_name_without_ext}-第{round_count}轮游戏开始 ===")
        # 对战
        safe_click(device, 500, 1500)
        time.sleep(0.5)
        ## 下牌操作
        print("执行下牌操作...")
        drag_screen(device, 300, 1700, 300, 1400, duration=0.3)
        # 再来一局
        safe_click(device, 400, 1700)
        ## 计算挂机时间
        end_time = datetime.datetime.now()
        # 计算并显示时间差
        hours, minutes, seconds = calculate_time_difference(start_time, end_time)
        print(f"\n{file_name_without_ext}-已挂机时间：{hours}小时{minutes}分钟{seconds}秒")
        # 重新挑战
        safe_click(device, 300, 1100)
        # take_screenshot_with_coordinates(device, f"{file_name_without_ext}-准备对战-{round_count}.png", show_grid=True, grid_step=100)


if __name__ == "__main__":
    main()
